package com.github.pig.admin.service.impl;

import com.github.pig.admin.activity.JumpTaskCmd;
import com.github.pig.admin.model.FrontInfoScspVo;
import com.github.pig.admin.model.ScspOpinionVo;
import com.github.pig.admin.model.TaskVo;
import com.github.pig.admin.service.ActAssigneeService;
import com.github.pig.admin.service.ProcessService;
import com.github.pig.admin.service.SysUserService;
import com.github.pig.admin.util.*;
import io.jsonwebtoken.Claims;
import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.*;
import org.activiti.engine.impl.RuntimeServiceImpl;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class ProcessServiceImpl implements ProcessService {
	@Autowired
	private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;
	@Autowired
	private ProcessEngine processEngine;
	@Autowired
	private ActAssigneeService actAssigneeService;


    @Override
	@Transactional
	public Result StartProcess(FrontInfoScspVo frontInfoScspVo) {
		if(StringUtils.isEmpty(frontInfoScspVo.getFromId())){
    		return ResultGenerator.genFailResult("获取数据失败");
    	}
		Map<String,Object> map=new HashMap<String,Object>();
		map.put("user",frontInfoScspVo.getOpId());
		map.put("FrontInfoScspVo",frontInfoScspVo);
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(frontInfoScspVo.getProcessKey(),map);
		if (processInstance == null) {
			return ResultGenerator.genFailResult("未识别key");
		}
		String processId = processInstance.getId();
		Result result = new Result();
		result.setMessage("申批流程提交成功");
		result.setCode(ResultCode.SUCCESS);
		result.setData(processId);
    	return result;
		
	}
	@Transactional
	public void deleteScsp(String scspId){
//		FrontInfoScsp scsp = selectByPrimaryKey(scspId);
//		if(StringUtils.isBlank(scspId)){
//			throw new MyException("参数错误");
//		}
//		runtimeService.deleteProcessInstance(scsp.getProcessId(),"客户经理取消流程");
	}

	@SuppressWarnings("unchecked")
	public List<ScspOpinionVo> findOptionList(String processId) {
		//获取流程实例
		ProcessInstance instance= runtimeService.createProcessInstanceQuery()
		          .processInstanceId(processId).singleResult();
        //保证运行ing
        List<ScspOpinionVo> optionList=new ArrayList<>();
        if(instance!=null){
          List<Task> tasks = this.taskService.createTaskQuery().processInstanceId(processId).orderByTaskCreateTime().desc().list();;
          Task task=tasks.get(0);
          Map<String, Object> variables = taskService.getVariables(task.getId());
          Object o = variables.get("");
          if(o!=null){
            /*获取历史审核信息*/
            optionList= ( List<ScspOpinionVo>) o;
          }
        }else{
            List<HistoricDetail> list = historyService.createHistoricDetailQuery().
                  processInstanceId(processId).list();
            HistoricVariableUpdate variable=null;
            for(HistoricDetail historicDetail:list){
              variable= (HistoricVariableUpdate) historicDetail;
              String variableName = variable.getVariableName();
              if("".equals(variableName)){
            	  optionList.clear();
            	  optionList.addAll((List<ScspOpinionVo>)variable.getValue());
              }
            }
        }
		return optionList;
	}

	public ReType showTaskList(TaskVo task, String page, String limit) {
		//创建任务查询
		TaskQuery qury=taskService.createTaskQuery()
				  .taskCandidateOrAssigned(task.getOpId());
//	    		  .processVariableValueEquals("type", ProcessType.SCSP_PROCESS);
		//查询条件
		if(StringUtils.isNotBlank(task.getFromUser())){
			qury.processVariableValueEquals("fromUser", task.getFromUser());
		}
		List<Task> taskList=qury.orderByTaskCreateTime().desc()
		  .listPage(Integer.valueOf(limit) * (Integer.valueOf(page) - 1), Integer.valueOf(limit));
		
	    List<TaskVo> tasks=new ArrayList<TaskVo>();
	    Map<String,Object> map=new HashMap<>();
	    TaskVo taskEntity=null;	 
	    for(Task task1:taskList){
	      map=taskService.getVariables(task1.getId());
	      FrontInfoScspVo scsp= (FrontInfoScspVo) map.get("FrontInfoScspVo");
	      List<ScspOpinionVo> opinionVos = (List<ScspOpinionVo>) map.get("opinionList");
	      taskEntity=new TaskVo(task1);
	      if(scsp!=null){
			  BeanUtils.copyProperties(scsp, taskEntity);
		  }
		  if(opinionVos!=null&&opinionVos.size()>0){
	      	taskEntity.setOpinionVoList(opinionVos);
		  }
	      tasks.add(taskEntity);
	    }
		return new ReType(taskList.size(),tasks);
	}
	/**
	 * 完成任务
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public String complete(ScspOpinionVo op) {
		Task task=taskService.createTaskQuery().taskId(op.getTaskId()).singleResult();
		Map<String, Object> variables = taskService.getVariables(op.getTaskId());
		FrontInfoScspVo scspVo= (FrontInfoScspVo) variables.get("FrontInfoScspVo");
		Map<String,Object> map=new HashMap<>();
		taskService.claim(op.getTaskId(),op.getUserId());//认领任务
		op.setBusinessId(scspVo.getFromId());
		op.setCreTime(new Date());
		op.setTaskName(task.getName());
		//审批信息叠加
		List<ScspOpinionVo> scspOptionList=new ArrayList<>();
		Object o = variables.get("opinionList");
		if(o!=null){
			scspOptionList= (List<ScspOpinionVo>) o;
		}
		scspOptionList.add(op);
		map.put("user",op.getOpId());
		map.put("opinionVo",op);
		map.put("opinionList",scspOptionList);
		taskService.complete(op.getTaskId(),map);
		return null;
	}

	/**
	 *检查信息是否完整
	 * @return
	 */
	private boolean completeInfoCheck( ) {
		boolean flag = true;

//		if (StringUtils.isBlank()) {
//
//		}
		return false;
	}

	public ReType showCompleteTaskList(ScspOpinionVo opinionVo, String page, String limit) {
		//创建任务查询
		HistoricTaskInstanceQuery qury=historyService.createHistoricTaskInstanceQuery()
				.taskAssignee(opinionVo.getUserId()).finished();
		List<HistoricTaskInstance> taskList=qury.orderByTaskCreateTime().desc()
				.listPage(Integer.valueOf(limit) * (Integer.valueOf(page) - 1), Integer.valueOf(limit));

		List<TaskVo> tasks=new ArrayList<TaskVo>();
		Map<String,Object> map=new HashMap<>();
		for(HistoricTaskInstance task1:taskList){
			TaskVo taskEntity=new TaskVo();
			taskEntity.setId(task1.getId());
			taskEntity.setName(task1.getName());
			taskEntity.setCreateTime(task1.getCreateTime());
			taskEntity.setAssignee(task1.getAssignee());
			taskEntity.setProcessDefinitionId(task1.getProcessDefinitionId());
			taskEntity.setProcessInstanceId(task1.getProcessInstanceId());
			taskEntity.setDescription(task1.getDescription());
			taskEntity.setCategory(task1.getCategory());
			List<HistoricDetail> list = historyService.createHistoricDetailQuery().executionId(task1.getExecutionId()).list();
			for(HistoricDetail detail : list){
				HistoricVariableUpdate variable = (HistoricVariableUpdate) detail;
				if("opinionVo".equals(variable.getVariableName())){
					ScspOpinionVo opv = (ScspOpinionVo) variable.getValue();
					taskEntity.setOpinion(opv.getOpinion());
					taskEntity.setOpId(opv.getOpId());
					taskEntity.setOpName(opv.getOpName());
					taskEntity.setCreateTime(opv.getCreTime());
				}
				if("FrontInfoScspVo".equals(variable.getVariableName())){
					FrontInfoScspVo fvo = (FrontInfoScspVo) variable.getValue();
					taskEntity.setFromId(fvo.getFromId());
					taskEntity.setFromTable(fvo.getFromTable());
					taskEntity.setTitle(fvo.getTitle());
					taskEntity.setFromUser(fvo.getFromUser());
				}
				if("opinionList".equals(variable.getVariableName())){
					List<ScspOpinionVo> opinionVos = (List<ScspOpinionVo>) variable.getValue();
					taskEntity.setOpinionVoList(opinionVos);

				}			}
			tasks.add(taskEntity);
		}
		return new ReType(taskList.size(),tasks);
	}


	//回退任务
	public void taskBack(ScspOpinionVo op) {
		// 添加意见
		if (StringUtils.isNotBlank(op.getProcessInstancesId()) && StringUtils.isNotBlank(op.getOpinion())){
			taskService.addComment(op.getTaskId(), op.getProcessInstancesId(), op.getOpinion());
			//插入时间
			Date now = new Date();
			actAssigneeService.updateActInstDate(now,op.getTaskId());
		}
		Map<String, Object> variables = new HashMap<>();
		taskBack(getCurrentTask(op.getProcessInstancesId()), variables);
	}
	private TaskEntity getCurrentTask(String procInsId) {
		return (TaskEntity) taskService.createTaskQuery().processInstanceId(procInsId).active().singleResult();
	}

	/**
	 * 任务后退至指定活动
	 */
	public void taskBack(TaskEntity currentTaskEntity, Map<String, Object> variables) {
		ActivityImpl activity = (ActivityImpl) ProcessDefUtils
				.getActivity(processEngine, currentTaskEntity.getProcessDefinitionId(), currentTaskEntity.getTaskDefinitionKey())
				.getIncomingTransitions().get(0).getSource();
		jumpTask(currentTaskEntity, activity, variables);
	}

	private void jumpTask(TaskEntity currentTaskEntity, ActivityImpl targetActivity, Map<String, Object> variables) {


		CommandExecutor commandExecutor = ((RuntimeServiceImpl) runtimeService).getCommandExecutor();
		commandExecutor.execute(new JumpTaskCmd(currentTaskEntity, targetActivity, variables));
	}


}
